{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "using ProgressMeter\n",
    "using Base.Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "using ParserCombinator\n",
    "using NamedColors\n",
    "using Colors\n",
    "using AutoHashEquals\n",
    "using AbstractTrees"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ParserCombinator.Seq(:tgrammer,ParserCombinator.Matcher[ParserCombinator.Delayed(:athing,ParserCombinator.Alt(:Alt,ParserCombinator.Matcher[ParserCombinator.Transform(:thing,ParserCombinator.Depth(:Depth,ParserCombinator.Pattern(:Pattern,\"\\\\w\",r\"^(?:\\w)(.??)\",()),0,9223372036854775807,true),ParserCombinator.#50),ParserCombinator.Seq(:things,ParserCombinator.Matcher[ParserCombinator.Delayed(#= circular reference @-5 =#),ParserCombinator.Drop(:Drop,ParserCombinator.Equal(:Equal,\" \")),ParserCombinator.Delayed(#= circular reference @-5 =#)])])),ParserCombinator.Eos(:Eos)])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@with_names begin\n",
    "    athing = Delayed()\n",
    "    thing = Repeat(p\"\\w\") |> join\n",
    "    things = athing + E\" \" + athing\n",
    "    athing.matcher = thing | things\n",
    "    tgrammer = athing + Eos()\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{Any,1}:\n",
       " \"a\""
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "parse_dbg(\"a\", tgrammer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "start(\"aa\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('a',2)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "next(\"abcde\",1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "LoadError",
     "evalue": "UndefVarError: Trie not defined",
     "output_type": "error",
     "traceback": [
      "UndefVarError: Trie not defined",
      ""
     ]
    }
   ],
   "source": [
    "function common_prefix_key(strings::Trie, source)\n",
    "    Task() do \n",
    "        node = strings\n",
    "        ii = start(source)\n",
    "        while !done(source, ii)\n",
    "            s, next_ii = next(source, ii)\n",
    "            if haskey(node.children, s)\n",
    "                node = node.children[s]\n",
    "                if node.is_key\n",
    "                    produce(ii)\n",
    "                end\n",
    "                ii=next_ii\n",
    "            else\n",
    "                break\n",
    "            end\n",
    "        end\n",
    "    end\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "LoadError",
     "evalue": "UndefVarError: Trie not defined",
     "output_type": "error",
     "traceback": [
      "UndefVarError: Trie not defined",
      ""
     ]
    }
   ],
   "source": [
    "strings = Trie([\"abc\", \"aabbc\", \"aabbcc\", \"aaabc\", \"aax\"]);\n",
    "\n",
    "common_prefix_key(strings, \"aa\") |> collect"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "LoadError",
     "evalue": "UndefVarError: Trie not defined",
     "output_type": "error",
     "traceback": [
      "UndefVarError: Trie not defined",
      ""
     ]
    }
   ],
   "source": [
    "function check_prefix_key(\n",
    "        strings::Trie,\n",
    "        source::AbstractString;\n",
    "        longest::Bool = true)\n",
    "    node = strings\n",
    "    foundat = -1\n",
    "    \n",
    "    function cknode!(ii)\n",
    "        if node.is_key\n",
    "            foundat = ii\n",
    "        end\n",
    "        node.is_key\n",
    "    end\n",
    "\n",
    "    for (ii, s) in zip(0:length(source), source)\n",
    "        if haskey(node.children, s)\n",
    "            node = node.children[s]\n",
    "            if cknode!(ii+1) && !longest\n",
    "                # if we are looking for shortest then we found it.\n",
    "                break \n",
    "            end\n",
    "        else\n",
    "            break\n",
    "        end\n",
    "    end\n",
    "    foundat <= 0 ?  Nullable{String}() : Nullable(source[1:foundat])\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1m\u001b[37mCheck for prefix with tries: \u001b[0m\u001b[1m\u001b[31mError During Test\n",
      "\u001b[0m  Got an exception of type UndefVarError outside of a @test\n",
      "  UndefVarError: Trie not defined\n",
      "   in macro expansion; at ./In[10]:2 [inlined]\n",
      "   in macro expansion; at ./test.jl:672 [inlined]\n",
      "   in anonymous at ./<missing>:?\n",
      "   in include_string(::String, ::String) at ./loading.jl:441\n",
      "   in execute_request(::ZMQ.Socket, ::IJulia.Msg) at /home/ubuntu/.julia/v0.5/IJulia/src/execute_request.jl:175\n",
      "   in eventloop(::ZMQ.Socket) at /home/ubuntu/.julia/v0.5/IJulia/src/eventloop.jl:8\n",
      "   in (::IJulia.##9#15)() at ./task.jl:360\n",
      "\u001b[1m\u001b[37mTest Summary:               | \u001b[0m\u001b[1m\u001b[31mError  \u001b[0m\u001b[1m\u001b[34mTotal\u001b[0m\n",
      "  Check for prefix with tries | \u001b[1m\u001b[31m    1  \u001b[0m\u001b[1m\u001b[34m    1\u001b[0m\n"
     ]
    },
    {
     "ename": "LoadError",
     "evalue": "Some tests did not pass: 0 passed, 0 failed, 1 errored, 0 broken.",
     "output_type": "error",
     "traceback": [
      "Some tests did not pass: 0 passed, 0 failed, 1 errored, 0 broken.",
      "",
      " in finish(::Base.Test.DefaultTestSet) at ./test.jl:495",
      " in macro expansion; at ./test.jl:679 [inlined]",
      " in anonymous at ./<missing>:?"
     ]
    }
   ],
   "source": [
    "@testset \"Check for prefix with tries\" begin\n",
    "    strings = Trie([\"abc\", \"aabbc\", \"aabbcc\", \"aaabc\", \"aax\"]);\n",
    "\n",
    "    @test check_prefix_key(strings, \"ab\"; longest=false) |> isnull\n",
    "    @test check_prefix_key(strings, \"abc\"; longest=false) |> get ==\"abc\"\n",
    "    @test check_prefix_key(strings, \"abcx\"; longest=false) |> get == \"abc\"\n",
    "    @test check_prefix_key(strings, \"aabbcc\"; longest=false) |> get == \"aabbc\"\n",
    "    @test check_prefix_key(strings, \"aabbcx\"; longest=false) |> get == \"aabbc\"\n",
    "\n",
    "\n",
    "    @test check_prefix_key(strings, \"ab\") |> isnull\n",
    "    @test check_prefix_key(strings, \"abc\") |> get ==\"abc\"\n",
    "    @test check_prefix_key(strings, \"abcx\") |> get == \"abc\"\n",
    "    @test check_prefix_key(strings, \"aabbcc\") |> get == \"aabbcc\"\n",
    "    @test check_prefix_key(strings, \"aabbcx\") |> get == \"aabbc\"    \n",
    "end;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "LoadError",
     "evalue": "UndefVarError: Trie not defined",
     "output_type": "error",
     "traceback": [
      "UndefVarError: Trie not defined",
      ""
     ]
    }
   ],
   "source": [
    "@auto_hash_equals type EqualsOneOf<:Matcher\n",
    "    name::Symbol\n",
    "    strings::Trie\n",
    "    longest::Bool\n",
    "    function EqualsOneOf(strings; longest=true) \n",
    "        new(:EqualsOneOf, Trie(strings), longest)\n",
    "    end\n",
    "end\n",
    "\n",
    "always_print(::EqualsOneOf) = true\n",
    "\n",
    "function execute(k::Config, m::EqualsOneOf, s::Clean, i)\n",
    "    for x in m.string\n",
    "        if done(k.source, i)\n",
    "            return FAILURE\n",
    "        end\n",
    "        y, i = next(k.source, i)\n",
    "        if x != y\n",
    "            return FAILURE\n",
    "        end\n",
    "    end\n",
    "    Success(DIRTY, i, Any[m.string])\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "using DataStructures"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "find_POCs"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"\"\"\n",
    "Digests a set of raw color strings,\n",
    "and finds lists of the \"Parts Of Colors\" (poc), similar to Parts of speech (pos).\n",
    "These are\n",
    "\n",
    "- `base_colors`: Normal colors people use all the time, eg `red`, `green`, `tan`, `purple`\n",
    "- `generic_modifiers`: Adjectives that people apply to colors, `dark`, `pale` etc. Also includes (for POC tagging purposes) things like `greenish` and `bluey`. Though they should be parsed differently in next step \n",
    "- `nounish_colors`: Things that are not normally considered colors but use like them anyway (and don't thus normally occur with genric modifiers), eg `blood`, `puke`, `booger`\n",
    "- `nounish_modifiers`: Nouns that are attached to specific colors, that indicate a specific type of that color.  Eg grass as in \"grass green\", \"ghost\" as in \"ghost white\"\n",
    "- `conjunctives`: Words that go between two colors to join them. eg \"with\".\n",
    "\n",
    "In general be confidant on the identification of all `base_colors` and `generic_modifiers`,\n",
    "if capturing from a large number of `raw_color_names`\n",
    "Be less confidant of the indification of `nounish_colors` and `nounish_modifiers`\n",
    "have no confidance in the identifaction of `conjuctives, they are for debugging purposes\n",
    "\"\"\"\n",
    "function find_POCs(raw_color_names, nounish_cutoff = 2)\n",
    "    split_on = [' ','-','/']\n",
    "    first_color_words = first.(split.(raw_color_names, [split_on]))\n",
    "    last_color_words =  last.(split.(raw_color_names,  [split_on]))\n",
    "\n",
    "    first_color_counts = counter(first_color_words)\n",
    "    last_color_counts = counter(last_color_words)\n",
    "\n",
    "    base_colors = String[] #Generic colors\n",
    "    nounish_colors = String[] #Words that are used as colors but probable are not normally recognised as suc\n",
    "\n",
    "    modifiers = String[] #Adjectives that modify a color\n",
    "    nounish_modifiers = String[] #Noun parts that describe a paricular color, eg lawn ad in lawn green\n",
    "\n",
    "\n",
    "    for name in union(first_color_words, last_color_words)\n",
    "        fcount = first_color_counts[name] \n",
    "        lcount = last_color_counts[name]\n",
    "        if fcount  <= lcount \n",
    "            #including On a tie\n",
    "            if fcount <= nounish_cutoff\n",
    "                push!(nounish_colors, name)\n",
    "            else\n",
    "                push!(base_colors, name)\n",
    "            end\n",
    "        else\n",
    "            if fcount <= nounish_cutoff\n",
    "                push!(nounish_modifiers, name)\n",
    "            else\n",
    "                push!(modifiers, name)\n",
    "            end\n",
    "        end\n",
    "    end\n",
    "    \n",
    "    mid(x) =  length(x)>2 ? x[2:end-1]: []\n",
    "    conjunctives = Base.flatten(mid.(split.(raw_color_names, [split_on]))) |> Set \n",
    "    setdiff!(conjunctives, first_color_words)\n",
    "    setdiff!(conjunctives, last_color_words) #remove anything already categorised\n",
    "    \n",
    "    \n",
    "    base_colors, modifiers, nounish_colors, nounish_modifiers, conjunctives\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(String[\"purple\",\"blue\",\"turquoise\",\"grey\",\"violet\",\"aqua\",\"brown\",\"orange\",\"green\",\"tan\",\"yellow\",\"rose\",\"lime\",\"red\",\"olive\",\"seafoam\",\"pink\",\"lavender\",\"teal\",\"navy\"],String[\"dark\",\"light\",\"mud\",\"greenish\",\"pale\",\"pea\",\"slate\",\"deep\",\"bluey\",\"faded\"  …  \"bluish\",\"very\",\"purplish\",\"off\",\"purpleish\",\"shit\",\"golden\",\"poop\",\"cool\",\"steel\"],String[\"celery\",\"chocolate\",\"heliotrope\",\"puce\",\"scarlet\",\"copper\",\"ocher\",\"liliac\",\"rouge\",\"custard\"  …  \"heather\",\"sandstone\",\"lavendar\",\"siena\",\"cotta\",\"soup\",\"rod\",\"urple\",\"cheese\",\"shell\"],String[\"grass\",\"lipstick\",\"pine\",\"twilight\",\"cornflower\",\"pumpkin\",\"cerulean\",\"carnation\",\"clay\",\"jade\"  …  \"eggshell\",\"night\",\"sunny\",\"indian\",\"clear\",\"stormy\",\"sunshine\",\"murky\",\"key\",\"hospital\"],Set(Any[\"a\",\"and\",\"out\",\"gum\",\"with\",\"of\",\"engine\",\"hint\"]))"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(base_colors, \n",
    "modifiers,\n",
    "nounish_colors,\n",
    "nounish_modifiers,\n",
    "conjunctives) = find_POCs(collect(keys(load_xkcd())))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "using ParserCombinator\n",
    "\n",
    "\n",
    "abstract AbstractColorBit\n",
    "abstract AbstractModifier<:AbstractColorBit\n",
    "\n",
    "abstract AbstractColorDesc<:AbstractColorBit\n",
    "abstract AbstractColorName<:AbstractColorDesc\n",
    "abstract AbstractCombinedColor<:AbstractColorDesc\n",
    "\n",
    "\n",
    "@auto_hash_equals immutable BaseColorName{S<:AbstractString} <:AbstractColorName\n",
    "    val::S\n",
    "end\n",
    "\n",
    "@auto_hash_equals immutable NounishColorName{S<:AbstractString} <:AbstractColorName\n",
    "    val::S\n",
    "end\n",
    "\n",
    "@auto_hash_equals immutable GenericModifier{S<:AbstractString} <:AbstractModifier \n",
    "    val::S \n",
    "end\n",
    "\n",
    "@auto_hash_equals immutable NounishModifier{S<:AbstractString} <:AbstractModifier \n",
    "    val::S \n",
    "end\n",
    "\n",
    "@auto_hash_equals immutable PostFixedColorModifier{\n",
    "        S<:AbstractString,\n",
    "        V<:AbstractColorDesc}<:AbstractModifier\n",
    "    val::V\n",
    "    suf::S\n",
    "end\n",
    "\n",
    "@auto_hash_equals immutable BinaryOpedColor{\n",
    "        S<:AbstractString,\n",
    "        V1<:AbstractColorDesc,\n",
    "        V2<:AbstractColorDesc} <:AbstractCombinedColor \n",
    "    val1::V1\n",
    "    op::S\n",
    "    val2::V2\n",
    "end\n",
    "\n",
    "@auto_hash_equals immutable ModifiedColor{\n",
    "        S<:AbstractModifier, \n",
    "        V<:AbstractColorDesc}<:AbstractCombinedColor\n",
    "    mod::S\n",
    "    val::V\n",
    "end\n",
    "\n",
    "@auto_hash_equals immutable PostFixedColor{\n",
    "        S<:AbstractString,\n",
    "        V<:AbstractColorDesc}<:AbstractCombinedColor\n",
    "    val::V\n",
    "    suf::S\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "function AbstractTrees.children{T<:AbstractColorBit}(v::T)\n",
    "    fnames = fieldnames(T)\n",
    "    getfield.([v], fnames)\n",
    "end\n",
    "\n",
    "function AbstractTrees.printnode{T<:AbstractColorBit}(io::IO, ::T)\n",
    "    showcompact(io,T.name)\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"\""
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@with_names begin\n",
    "\n",
    "    #word = Repeat(p\"\\w\"; greedy=false, backtrack=true) |> join #can't use regex `p\"\\w+\"` as it has no bactracking\n",
    "    #word = Repeat(Alt(Equal.('a':'z')...)) |> join\n",
    "    word = p\"\\w+\"\n",
    "    \n",
    "    col  = Alt(Equal.(base_colors)...) >  BaseColorName\n",
    "    nmod = word > NounishModifier\n",
    "    ncol = word > NounishColorName\n",
    "    gmod  = Alt(Equal.(modifiers)...)  > GenericModifier\n",
    "\n",
    "\n",
    "    color = Delayed()\n",
    "    binop = e\" \"#(e\" with a hint of \" | e\"ish \" \n",
    "            #| e\"y \" | e\"/\" | e\"-\")\n",
    "\n",
    "    binaryoped = color + binop + color > BinaryOpedColor\n",
    "\n",
    "    postfix = e\"y\" | e\"ish\" | e\"\"\n",
    "    postfixed = color + postfix > PostFixedColor\n",
    "    \n",
    "    pmod = col + postfix > PostFixedColorModifier\n",
    "    mod = pmod | gmod | nmod\n",
    "    modded = mod +  E\" \" + color > ModifiedColor\n",
    "    \n",
    "\n",
    "    color.matcher = (col | modded | ncol)\n",
    "    colorgrammar = color + Eos();\n",
    "end\n",
    "\"\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Any[ModifiedColor{PostFixedColorModifier{String,BaseColorName{String}},ModifiedColor{PostFixedColorModifier{String,BaseColorName{String}},BaseColorName{String}}}(PostFixedColorModifier{String,BaseColorName{String}}(BaseColorName{String}(\"blue\"),\"ish\"),ModifiedColor{PostFixedColorModifier{String,BaseColorName{String}},BaseColorName{String}}(PostFixedColorModifier{String,BaseColorName{String}}(BaseColorName{String}(\"red\"),\"ish\"),BaseColorName{String}(\"green\")))]\n",
      "└─ ModifiedColor\n",
      "   ├─ PostFixedColorModifier\n",
      "   │  ├─ BaseColorName\n",
      "   │  │  └─ \"blue\"\n",
      "   │  └─ \"ish\"\n",
      "   └─ ModifiedColor\n",
      "      ├─ PostFixedColorModifier\n",
      "      │  ├─ BaseColorName\n",
      "      │  │  └─ \"red\"\n",
      "      │  └─ \"ish\"\n",
      "      └─ BaseColorName\n",
      "         └─ \"green\"\n"
     ]
    }
   ],
   "source": [
    "t = parse_one(\"blueish redish green\", (colorgrammar); delegate=Cache)\n",
    "print_tree(STDOUT, t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Any[ModifiedColor{NounishModifier{SubString{String}},NounishColorName{SubString{String}}}(NounishModifier{SubString{String}}(\"gob\"),NounishColorName{SubString{String}}(\"rat\"))]\n",
      "└─ ModifiedColor\n",
      "   ├─ NounishModifier\n",
      "   │  └─ \"gob\"\n",
      "   └─ NounishColorName\n",
      "      └─ \"rat\"\n"
     ]
    }
   ],
   "source": [
    "t = parse_one(\"gob rat\", colorgrammar; delegate=Cache)\n",
    "print_tree(STDOUT, t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{Any,1}:\n",
       " ModifiedColor{NounishModifier{SubString{String}},NounishColorName{SubString{String}}}(NounishModifier{SubString{String}}(\"Grass\"),NounishColorName{SubString{String}}(\"Green\"))"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "parse_one(\"Grass Green\", colorgrammar)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1m\u001b[31mTest Failed\n",
      "\u001b[0m  Expression: parse_one(\"redish blue\",colorgrammar) |> first == BinaryOpedColor(BaseColorName(\"red\"),\"ish \",BaseColorName(\"blue\"))\n",
      "   Evaluated: ModifiedColor{PostFixedColorModifier{String,BaseColorName{String}},BaseColorName{String}}(PostFixedColorModifier{String,BaseColorName{String}}(BaseColorName{String}(\"red\"),\"ish\"),BaseColorName{String}(\"blue\")) == BinaryOpedColor{String,BaseColorName{String},BaseColorName{String}}(BaseColorName{String}(\"red\"),\"ish \",BaseColorName{String}(\"blue\"))\n"
     ]
    },
    {
     "ename": "LoadError",
     "evalue": "There was an error during testing",
     "output_type": "error",
     "traceback": [
      "There was an error during testing",
      "",
      " in record(::Base.Test.FallbackTestSet, ::Base.Test.Fail) at ./test.jl:397",
      " in do_test(::Base.Test.Returned, ::Expr) at ./test.jl:281"
     ]
    }
   ],
   "source": [
    "using Base.Test\n",
    "@test parse_one(\"blue\", colorgrammar) |> first == BaseColorName(\"blue\")\n",
    "@test parse_one(\"redish blue\", colorgrammar) |> first ==\n",
    "    BinaryOpedColor(BaseColorName(\"red\"),\"ish \",BaseColorName(\"blue\"))\n",
    "@test parse_one(\"redish green-red\", colorgrammar) |> first ==\n",
    "BinaryOpedColor(BaseColorName(\"red\"),\"ish \", BinaryOpedColor(BaseColorName(\"green\"), \"-\", BaseColorName(\"red\")))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Any[ModifiedColor{PostFixedColorModifier{String,BaseColorName{String}},BaseColorName{String}}(PostFixedColorModifier{String,BaseColorName{String}}(BaseColorName{String}(\"green\"),\"ish\"),BaseColorName{String}(\"red\"))]\n",
      "└─ ModifiedColor\n",
      "   ├─ PostFixedColorModifier\n",
      "   │  ├─ BaseColorName\n",
      "   │  │  └─ \"green\"\n",
      "   │  └─ \"ish\"\n",
      "   └─ BaseColorName\n",
      "      └─ \"red\"\n"
     ]
    }
   ],
   "source": [
    "t=\n",
    "print_tree(STDOUT, t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{Any,1}:\n",
       " \"a\""
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "parse_one(\"a\", e\"a\" + Eos() + Eos())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "grass green\n",
      "Progress:   0%|                                         |  ETA: 0:13:51lipstick\n"
     ]
    },
    {
     "ename": "LoadError",
     "evalue": "InterruptException:",
     "output_type": "error",
     "traceback": [
      "InterruptException:",
      "",
      " in schedule_and_wait(::Task, ::Void) at ./event.jl:110",
      " in consume(::Task) at ./task.jl:269",
      " in once at /home/ubuntu/.julia/v0.5/ParserCombinator/src/core/parsers.jl:182 [inlined]",
      " in (::ParserCombinator.##single_result#36#38{Array{Any,1},DataType})(::Array{Any,1}, ::Function, ::SubString{String}, ::ParserCombinator.Seq) at /home/ubuntu/.julia/v0.5/ParserCombinator/src/core/parsers.jl:193",
      " in (::ParserCombinator.#single_result#37)(::SubString{String}, ::ParserCombinator.Seq) at /home/ubuntu/.julia/v0.5/ParserCombinator/src/core/parsers.jl:192",
      " in macro expansion; at ./In[25]:4 [inlined]",
      " in macro expansion; at /home/ubuntu/.julia/v0.5/ProgressMeter/src/ProgressMeter.jl:473 [inlined]",
      " in anonymous at ./<missing>:?"
     ]
    }
   ],
   "source": [
    "@showprogress for colorstring in collect(keys(load_xkcd()))\n",
    "    println(colorstring)\n",
    "    flush(STDOUT)\n",
    "    parse_one(colorstring, colorgrammar)\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1-element Array{String,1}:\n",
       " \"red\""
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "children(BaseColorName(\"red\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "LoadError",
     "evalue": "MethodError: no method matching getindex(::Void, ::Int64)",
     "output_type": "error",
     "traceback": [
      "MethodError: no method matching getindex(::Void, ::Int64)",
      ""
     ]
    }
   ],
   "source": [
    "T = typeof(t[1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "ename": "LoadError",
     "evalue": "UndefVarError: T not defined",
     "output_type": "error",
     "traceback": [
      "UndefVarError: T not defined",
      ""
     ]
    }
   ],
   "source": [
    "T.name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 0.5.0",
   "language": "julia",
   "name": "julia-0.5"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "0.5.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
